package com.hebeiboruan.controller.system;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.jwt.JWTUtil;
import com.hebeiboruan.common.exception.system.user.UserResultEnum;
import com.hebeiboruan.common.uitl.FileUtil;
import com.hebeiboruan.common.uitl.JwtUtils;
import com.hebeiboruan.entity.system.RoleRouter;
import com.hebeiboruan.entity.system.UserRole;
import com.hebeiboruan.router.service.RoleRouterService;
import com.hebeiboruan.router.service.RouterService;
import com.hebeiboruan.entity.DTO.system.SearchRouterDTO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hebeiboruan.router.listener.RouterListener;
import com.hebeiboruan.entity.system.Router;
import com.hebeiboruan.common.HttpMessage;
import com.hebeiboruan.common.exception.CommonException;
import java.time.LocalDateTime;
import com.hebeiboruan.common.exception.ServiceResultEnum;

import javax.servlet.http.HttpServletRequest;
import com.alibaba.excel.EasyExcel;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

import com.hebeiboruan.userRole.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hebeiboruan.common.uitl.LoggerUtil;
@RestController
@RequestMapping("/router")
public class RouterController {
    @Value("${project.staticPath}")
    private String path;
    private static Logger log = LoggerFactory.getLogger(RouterController.class);
    private RouterService routerService;
    private RoleRouterService roleRouterService;
    private UserRoleService userRoleService;
    @Autowired
    public void setUserRoleService(UserRoleService userRoleService) {
        this.userRoleService = userRoleService;
    }

    @Autowired
    public void setRoleRouterService(RoleRouterService roleRouterService) {
        this.roleRouterService = roleRouterService;
    }

    @Autowired
    public void setRouterService(RouterService routerService) {
    this.routerService = routerService;
    }
    private RedisTemplate redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 验证token
     *
     * @param token 令 牌
     * @return {@link HttpMessage}
     */
    @GetMapping("/verify/{token}")
    public HttpMessage verify(@PathVariable String token){
        try{
            redisTemplate.hasKey(token);
            return HttpMessage.data(true);
        }catch (Exception e){
            return HttpMessage.result(UserResultEnum.POWER_ERROR);
        }
    }
    @GetMapping("/getAllRouter/{page}/{limit}")
    public HttpMessage getAllRouter(@PathVariable Integer page,@PathVariable Integer limit,HttpServletRequest request){
        HttpMessage.isBlank(page,limit);
        Page<Router> page1 = routerService.page(new Page<>(page, limit),
                new QueryWrapper<Router>()
                        .isNull("router")
        );
        page1.getRecords().forEach(item->{
            item.setChild(routerService.list(new QueryWrapper<Router>()
                    .eq("router",item.getRouterNo())
            ));
        });
        return HttpMessage.data(page1);
    }
    @GetMapping("/showRouter")
    public HttpMessage showRouter(HttpServletRequest request){
        List<String> roles=new ArrayList<>();
        userRoleService.
                list(
                        new QueryWrapper<UserRole>()
                                .eq("user", JwtUtils.decodeRsa(request)
                                        .get("userNo",Integer.class)
                                )
                ).forEach(item->{
                    roles.add(item.getRole().toString());
                });
        String join = String.join(",", ArrayUtil.toArray(roles, String.class));


        List<Router> page1 = routerService.list(
                new QueryWrapper<Router>()
                        .isNull("router")
                        .exists("select 1 from `br_role_router` WHERE role in ("+join+") and router=router_no")
        );
        page1.forEach(item->{
            item.setChild(routerService.list(new QueryWrapper<Router>()
                    .eq("router",item.getRouterNo())
                    .exists("select 1 from `br_role_router` WHERE role in ("+join+") and router=router_no")

            ));
        });
        return HttpMessage.data(page1);
    }
    @GetMapping("/getAllRouter")
    public HttpMessage getAllRouter(){

        return HttpMessage.data(routerService.list());
    }
    @PostMapping("/searchRouter")
    public HttpMessage searchUser(SearchRouterDTO search){
    HttpMessage.isBlank(search.getPage(),search.getLimit());
    QueryWrapper<Router> wrapper=new QueryWrapper<>();
        if (search.getRouterPath() != null) {
        wrapper.like("router_path",search.getRouterPath());
        }
        if (search.getRouterComponent() != null) {
        wrapper.like("router_component",search.getRouterComponent());
        }
        if (search.getRouterName() != null) {
        wrapper.like("router_name",search.getRouterName());
        }
    return HttpMessage.data(routerService.page(new Page<>(search.getPage(),search.getLimit()),wrapper));
    }
    @PutMapping("/addRouter")
    public HttpMessage addRouter(Router router,MultipartFile file, HttpServletRequest request) throws IOException {
        HttpMessage.isBlank( router.getRouterPath(), router.getRouterComponent(), router.getRouterName());
        if (file != null) {
            router.setRouterIcon(FileUtil.upload(file,path+"/"));
        }
        try {
            routerService.save(router);
            return HttpMessage.result(ServiceResultEnum.INSERT_TRUE);
        }catch (Exception e){
            LoggerUtil.webError(e,request,log);
            throw new CommonException(ServiceResultEnum.INSERT_ERROR,e);
        }
    }
    @PostMapping("/editRouter")
    public HttpMessage editRouter(Router router,MultipartFile file, HttpServletRequest request) throws IOException {
        HttpMessage.isBlank( router.getRouterPath(), router.getRouterComponent(), router.getRouterName());
        if (file != null) {
            router.setRouterIcon(FileUtil.upload(file,path+"/"));
        }
        try {
            routerService.updateById(router);
            return HttpMessage.result(ServiceResultEnum.UPDATE_TRUE);
        }catch (Exception e){
            LoggerUtil.webError(e,request,log);
            throw new CommonException(ServiceResultEnum.UPDATE_ERROR,e);
        }
    }
    @DeleteMapping("/removeRouter/{routerNo}")
    public HttpMessage removeRouter(@PathVariable Integer routerNo,HttpServletRequest request){
        HttpMessage.isBlank(routerNo);
        try {
            routerService.removeById(routerNo);
            return HttpMessage.result(ServiceResultEnum.REMOVE_TRUE);
        }catch (Exception e){
            LoggerUtil.webError(e,request,log);
            throw new CommonException(ServiceResultEnum.REMOVE_ERROR,e);
        }

    }
    @DeleteMapping("/batchRemoveRouter/{id}")
    public HttpMessage batchRemoveRouter(@PathVariable String id){
        HttpMessage.isBlank(id);
        try{
            routerService.removeBatchByIds(Arrays.asList(id.split(",")));
            return HttpMessage.result(ServiceResultEnum.REMOVE_TRUE);
        }catch (Exception e){
            throw new CommonException(ServiceResultEnum.BATCH_REMOVE_ERROR,e);
        }

    }

    @PostMapping("/batchAddRouter")
    public HttpMessage batchAddRouter(@RequestParam("router")List<MultipartFile> router) {
        router.forEach(file->{
                try {
                    EasyExcel.read(file.getInputStream(), Router.class, new RouterListener(routerService)).sheet().doRead();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        return HttpMessage.result(ServiceResultEnum.BATCH_INSERT_TRUE);
    }

    @PostMapping("/batchOutRouter")
    public void batchOutRouter(@RequestParam("router") List<String> router, HttpServletResponse response) throws IOException {
        try{
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        //防止乱码
        String fileName ="D:/"+ URLEncoder.encode("routerData:"+LocalDateTime.now().toString(), "UTF-8").replaceAll("\\+", "%20")+".xlsx";
        List<Router> routerData=new ArrayList<>();
            router.forEach(item->{
                try {
                    routerData.add( new ObjectMapper().readValue(item,Router.class));
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
            });
                response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

                EasyExcel.write(response.getOutputStream(), Router.class).autoCloseStream(Boolean.FALSE).sheet("数据").doWrite(routerData);

        }catch (Exception e){
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");

            response.getWriter().println(HttpMessage.result(ServiceResultEnum.BATCH_OUT_ERROR));
        }
    }
    @GetMapping("/getRoleRouter/{role}")
    public HttpMessage getRoleRouter(@PathVariable Integer role){
        return HttpMessage.data(roleRouterService.list(new QueryWrapper<RoleRouter>().eq("role",role)));
    }
    @PostMapping("/saveRoleRouter")
    public HttpMessage saveRoleRouter(Integer role,@RequestParam List<Integer> router){
        roleRouterService.remove(new QueryWrapper<RoleRouter>().eq("role",role));
        List<RoleRouter> list=new ArrayList<>();
        router.forEach(item->{
            RoleRouter roleRouter = new RoleRouter();
            roleRouter.setRole(role);
            roleRouter.setRouter(item);
            list.add(roleRouter);
        });
        roleRouterService.saveBatch(list);
        return HttpMessage.result(ServiceResultEnum.INSERT_TRUE);
    }
}


